package com.oracle2mysql.migration;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
import com.oracle2mysql.migration.HtmlDiffGenerator.FilePair;

/**
 * Oracle到MySQL的MyBatis迁移工具链主程序入口
 */
public class Main {
    
    private static final Logger logger = LoggerFactory.getLogger(Main.class);
    
    public static void main(String[] args) {
        logger.info("===== Oracle到MySQL的MyBatis迁移工具链 =====");
        
        try {
            // 1. 加载配置文件
            Properties config = loadConfig();
            
            // 2. 初始化工具链组件
            // 从JSON文件加载函数映射
            String functionMappingFile = System.getProperty("function.mapping.file", 
                    config.getProperty("function.mapping.file", "classpath:function-mapping.json"));
            
            FunctionMapper functionMapper = new FunctionMapper(config, functionMappingFile);
            SqlConverter sqlConverter = new SqlConverter(functionMapper, config);
            MyBatisXmlParser xmlParser = new MyBatisXmlParser(sqlConverter, config);
            
            // 3. 执行迁移任务
            // 优先使用系统属性中的配置，然后是配置文件中的配置，最后是默认值
            String inputDir = System.getProperty("input.dir", 
                    config.getProperty("input.dir", "./input"));
            String outputDir = System.getProperty("output.dir", 
                    config.getProperty("output.dir", "./output"));
            
            // 检查是否覆盖已存在的文件
            String overwriteProp = System.getProperty("overwrite", 
                    config.getProperty("overwrite", "true"));
            boolean overwrite = Boolean.parseBoolean(overwriteProp);
            config.setProperty("overwrite", String.valueOf(overwrite));
            
            // 获取是否生成HTML对比报告的配置
            String generateHtmlReportProp = System.getProperty("generate.html.report", 
                    config.getProperty("generate.html.report", "false"));
            boolean generateHtmlReport = Boolean.parseBoolean(generateHtmlReportProp);
            
            // 获取HTML报告输出路径
            String htmlReportPath = System.getProperty("html.report.path", 
                    config.getProperty("html.report.path", outputDir + "/sql-diff-report.html"));
            
            logger.info("开始处理MyBatis XML文件...");
            logger.info("输入目录: {}", inputDir);
            logger.info("输出目录: {}", outputDir);
            logger.info("函数映射文件: {}", functionMappingFile);
            logger.info("生成HTML对比报告: {}", generateHtmlReport);
            
            if (generateHtmlReport) {
                // 记录迁移前的文件列表，用于生成对比报告
                List<FilePair> filePairs = new ArrayList<>();
                collectFilePairs(inputDir, outputDir, filePairs);
                
                // 执行迁移
                xmlParser.processDirectory(inputDir, outputDir);
                
                // 生成HTML对比报告
                generateHtmlDiffReport(filePairs, htmlReportPath);
            } else {
                // 直接执行迁移
                xmlParser.processDirectory(inputDir, outputDir);
            }
            
            logger.info("迁移完成！");
            
        } catch (Exception e) {
            logger.error("迁移过程中发生错误: {}", e.getMessage(), e);
            throw new RuntimeException("迁移失败", e);
        }
    }
    
    /**
     * 收集文件对，用于生成对比报告
     */
    private static void collectFilePairs(String inputDir, String outputDir, List<FilePair> filePairs) {
        File inputFolder = new File(inputDir);
        
        if (!inputFolder.exists() || !inputFolder.isDirectory()) {
            return;
        }
        
        File[] files = inputFolder.listFiles();
        if (files == null) {
            return;
        }
        
        for (File file : files) {
            if (file.isDirectory()) {
                // 递归处理子目录
                String subInputDir = inputDir + File.separator + file.getName();
                String subOutputDir = outputDir + File.separator + file.getName();
                collectFilePairs(subInputDir, subOutputDir, filePairs);
            } else if (file.getName().endsWith(".xml")) {
                // 添加文件对
                File outputFile = new File(outputDir + File.separator + file.getName());
                filePairs.add(new FilePair(file, outputFile));
            }
        }
    }
    
    /**
     * 生成HTML对比报告
     */
    private static void generateHtmlDiffReport(List<FilePair> filePairs, String htmlReportPath) {
        try {
            HtmlDiffGenerator diffGenerator = new HtmlDiffGenerator();
            diffGenerator.generateDiffReport(filePairs, htmlReportPath);
            logger.info("HTML对比报告已生成: {}", htmlReportPath);
        } catch (IOException e) {
            logger.error("生成HTML对比报告失败: {}", e.getMessage(), e);
        }
    }
    
    /**
     * 加载配置文件
     */
    private static Properties loadConfig() throws IOException {
        Properties properties = new Properties();
        
        // 1. 尝试从classpath加载默认配置
        try (InputStream is = Main.class.getClassLoader().getResourceAsStream("config.properties")) {
            if (is != null) {
                properties.load(is);
                logger.info("已加载classpath中的默认配置文件");
            }
        }
        
        // 2. 尝试从当前目录加载自定义配置文件
        File configFile = new File("config.properties");
        if (configFile.exists()) {
            try (FileInputStream fis = new FileInputStream(configFile)) {
                properties.load(fis);
                logger.info("已加载自定义配置文件");
            }
        } else {
            logger.info("自定义配置文件config.properties不存在，使用默认配置");
        }
        
        return properties;
    }
}